home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / out-of-phase-102-c / OutOfPhase 1.02 Source / OutOfPhase Folder / LFOGenerator.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  43.4 KB  |  1,452 lines  |  [TEXT/KAHL]

  1. /* LFOGenerator.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "LFOGenerator.h"
  31. #include "Memory.h"
  32. #include "EnvelopeState.h"
  33. #include "LFOSpecifier.h"
  34. #include "LFOListSpecifier.h"
  35. #include "FloatingPoint.h"
  36. #include "RandomNumbers.h"
  37. #include "Frequency.h"
  38. #include "Multisampler.h"
  39. #include "64BitMath.h"
  40. #include "SampleConsts.h"
  41.  
  42.  
  43. #define TWOPI ((float)6.28318530717958648)
  44.  
  45.  
  46. static long                                RandomSeed = PARKANDMILLERMINIMUM;
  47.  
  48.  
  49. typedef struct LFOOneStateRec
  50.     {
  51.         /* pointer to the LFO generating function */
  52.         float                                        (*GenFunction)(struct LFOOneStateRec* State, float Phase,
  53.                                                             float OriginalValue, float Amplitude);
  54.  
  55.         /* phase index counter */
  56.         FastFixedType                        CurrentPhase;
  57.  
  58.         /* the envelope controlling the amplitude. */
  59.         EvalEnvelopeRec*                LFOAmplitudeEnvelope;
  60.         /* the envelope controlling the frequency.  the value from here is periods per second */
  61.         EvalEnvelopeRec*                LFOFrequencyEnvelope;
  62.  
  63.         /* if this is True, then modulation is linear, otherwise modulation is */
  64.         /* exponential */
  65.         LFOArithSelect                    ModulationMode;
  66.  
  67.         /* what kind of operator are we using */
  68.         LFOOscTypes                            Operator;
  69.  
  70.         /* source information for the wave table */
  71.         MultiSampleRec*                    WaveTableSourceSelector;
  72.  
  73.         /* this is true if the wave table was defined */
  74.         MyBoolean                                WaveTableWasDefined;
  75.         /* number of frames per table */
  76.         long                                        FramesPerTable;
  77.         /* number of tables */
  78.         long                                        NumberOfTables;
  79.         /* raw wave table data array */
  80.         void**                                    WaveTableMatrix;
  81.         /* number of bits in the data for the table */
  82.         NumBitsType                            TableNumBits;
  83.         /* envelope controlling wave table index */
  84.         EvalEnvelopeRec*                WaveTableIndexEnvelope;
  85.  
  86.         /* modulation method */
  87.         LFOModulationTypes            ModulationMethod;
  88.  
  89.         /* link to the next one */
  90.         struct LFOOneStateRec*    Next;
  91.     } LFOOneStateRec;
  92.  
  93.  
  94. struct LFOGenRec
  95.     {
  96.         /* list of single LFO entries, which we sum up. */
  97.         LFOOneStateRec*                    LFOList;
  98.  
  99.         /* this is the correction factor from LFOFrequencyEnvelope which converts */
  100.         /* it from periods per second into an interval we can add to CurrentPhase */
  101.         FastFixedType                        CorrectionFactor;
  102.  
  103.         /* number of envelope clock pulses per second */
  104.         float                                        EnvelopeTicksPerSecond;
  105.  
  106.         /* link for caching records */
  107.         LFOGenRec*                            GarbageLink;
  108.     };
  109.  
  110.  
  111. /* prototypes */
  112. static float                        AddConst(LFOOneStateRec* State, float Phase,
  113.                                                     float OriginalValue, float Amplitude);
  114. static float                        AddSignSine(LFOOneStateRec* State, float Phase,
  115.                                                     float OriginalValue, float Amplitude);
  116. static float                        AddPosSine(LFOOneStateRec* State, float Phase,
  117.                                                     float OriginalValue, float Amplitude);
  118. static float                        AddSignTriangle(LFOOneStateRec* State, float Phase,
  119.                                                     float OriginalValue, float Amplitude);
  120. static float                        AddPosTriangle(LFOOneStateRec* State, float Phase,
  121.                                                     float OriginalValue, float Amplitude);
  122. static float                        AddSignSquare(LFOOneStateRec* State, float Phase,
  123.                                                     float OriginalValue, float Amplitude);
  124. static float                        AddPosSquare(LFOOneStateRec* State, float Phase,
  125.                                                     float OriginalValue, float Amplitude);
  126. static float                        AddSignRamp(LFOOneStateRec* State, float Phase,
  127.                                                     float OriginalValue, float Amplitude);
  128. static float                        AddPosRamp(LFOOneStateRec* State, float Phase,
  129.                                                     float OriginalValue, float Amplitude);
  130. static float                        AddSignFuzz(LFOOneStateRec* State, float Phase,
  131.                                                     float OriginalValue, float Amplitude);
  132. static float                        AddPosFuzz(LFOOneStateRec* State, float Phase,
  133.                                                     float OriginalValue, float Amplitude);
  134. static float                        AddWaveTable(LFOOneStateRec* State, float Phase,
  135.                                                     float OriginalValue, float Amplitude);
  136. static float                        MultConst(LFOOneStateRec* State, float Phase,
  137.                                                     float OriginalValue, float Amplitude);
  138. static float                        MultSignSine(LFOOneStateRec* State, float Phase,
  139.                                                     float OriginalValue, float Amplitude);
  140. static float                        MultPosSine(LFOOneStateRec* State, float Phase,
  141.                                                     float OriginalValue, float Amplitude);
  142. static float                        MultSignTriangle(LFOOneStateRec* State, float Phase,
  143.                                                     float OriginalValue, float Amplitude);
  144. static float                        MultPosTriangle(LFOOneStateRec* State, float Phase,
  145.                                                     float OriginalValue, float Amplitude);
  146. static float                        MultSignSquare(LFOOneStateRec* State, float Phase,
  147.                                                     float OriginalValue, float Amplitude);
  148. static float                        MultPosSquare(LFOOneStateRec* State, float Phase,
  149.                                                     float OriginalValue, float Amplitude);
  150. static float                        MultSignRamp(LFOOneStateRec* State, float Phase,
  151.                                                     float OriginalValue, float Amplitude);
  152. static float                        MultPosRamp(LFOOneStateRec* State, float Phase,
  153.                                                     float OriginalValue, float Amplitude);
  154. static float                        MultSignFuzz(LFOOneStateRec* State, float Phase,
  155.                                                     float OriginalValue, float Amplitude);
  156. static float                        MultPosFuzz(LFOOneStateRec* State, float Phase,
  157.                                                     float OriginalValue, float Amplitude);
  158. static float                        MultWaveTable(LFOOneStateRec* State, float Phase,
  159.                                                     float OriginalValue, float Amplitude);
  160. static float                        InvMultConst(LFOOneStateRec* State, float Phase,
  161.                                                     float OriginalValue, float Amplitude);
  162. static float                        InvMultSignSine(LFOOneStateRec* State, float Phase,
  163.                                                     float OriginalValue, float Amplitude);
  164. static float                        InvMultPosSine(LFOOneStateRec* State, float Phase,
  165.                                                     float OriginalValue, float Amplitude);
  166. static float                        InvMultSignTriangle(LFOOneStateRec* State, float Phase,
  167.                                                     float OriginalValue, float Amplitude);
  168. static float                        InvMultPosTriangle(LFOOneStateRec* State, float Phase,
  169.                                                     float OriginalValue, float Amplitude);
  170. static float                        InvMultSignSquare(LFOOneStateRec* State, float Phase,
  171.                                                     float OriginalValue, float Amplitude);
  172. static float                        InvMultPosSquare(LFOOneStateRec* State, float Phase,
  173.                                                     float OriginalValue, float Amplitude);
  174. static float                        InvMultSignRamp(LFOOneStateRec* State, float Phase,
  175.                                                     float OriginalValue, float Amplitude);
  176. static float                        InvMultPosRamp(LFOOneStateRec* State, float Phase,
  177.                                                     float OriginalValue, float Amplitude);
  178. static float                        InvMultSignFuzz(LFOOneStateRec* State, float Phase,
  179.                                                     float OriginalValue, float Amplitude);
  180. static float                        InvMultPosFuzz(LFOOneStateRec* State, float Phase,
  181.                                                     float OriginalValue, float Amplitude);
  182. static float                        InvMultWaveTable(LFOOneStateRec* State, float Phase,
  183.                                                     float OriginalValue, float Amplitude);
  184.  
  185.  
  186. static LFOGenRec*                    LFOGenFreeList = NIL;
  187. static LFOOneStateRec*        LFOOneStateFreeList = NIL;
  188.  
  189.  
  190. /* flush cached LFO generator records */
  191. void                                FlushLFOGeneratorRecords(void)
  192.     {
  193.         while (LFOGenFreeList != NIL)
  194.             {
  195.                 LFOGenRec*                Temp;
  196.  
  197.                 Temp = LFOGenFreeList;
  198.                 LFOGenFreeList = LFOGenFreeList->GarbageLink;
  199.                 ReleasePtr((char*)Temp);
  200.             }
  201.  
  202.         while (LFOOneStateFreeList != NIL)
  203.             {
  204.                 LFOOneStateRec*        Temp;
  205.  
  206.                 Temp = LFOOneStateFreeList;
  207.                 LFOOneStateFreeList = LFOOneStateFreeList->Next;
  208.                 ReleasePtr((char*)Temp);
  209.             }
  210.     }
  211.  
  212.  
  213. #if DEBUG
  214. static void                    ValidateLFOGen(LFOGenRec* LFOGen)
  215.     {
  216.         LFOGenRec*                Scan;
  217.  
  218.         Scan = LFOGenFreeList;
  219.         while (Scan != NIL)
  220.             {
  221.                 if (Scan == LFOGen)
  222.                     {
  223.                         PRERR(ForceAbort,"ValidateLFOGen:  it's on the free list");
  224.                     }
  225.                 Scan = Scan->GarbageLink;
  226.             }
  227.     }
  228. #else
  229. #define ValidateLFOGen(x) ((void)0)
  230. #endif
  231.  
  232.  
  233. #if DEBUG
  234. static void                    ValidateLFOOneState(LFOOneStateRec* OneState)
  235.     {
  236.         LFOOneStateRec*        Scan;
  237.  
  238.         Scan = LFOOneStateFreeList;
  239.         while (Scan != NIL)
  240.             {
  241.                 if (Scan == OneState)
  242.                     {
  243.                         PRERR(ForceAbort,"ValidateLFOOneState:  it's on the free list");
  244.                     }
  245.                 Scan = Scan->Next;
  246.             }
  247.     }
  248. #else
  249. #define ValidateLFOOneState(x) ((void)0)
  250. #endif
  251.  
  252.  
  253. /* create a new LFO generator based on a list of specifications */
  254. /* it returns the largest pre-origin time for all of the envelopes it contains */
  255. /* AmplitudeScaling and FrequencyScaling are provided primarily for frequency */
  256. /* LFO control; other LFOs are controlled through the accent parameters, and */
  257. /* should supply 1 (no scaling) for these parameters. */
  258. LFOGenRec*                    NewLFOGenerator(struct LFOListSpecRec* LFOListSpec,
  259.                                             long* MaxPreOriginTime, float Accent1, float Accent2,
  260.                                             float Accent3, float Accent4, float FrequencyHertz,
  261.                                             float HurryUp, float TicksPerSecond, float AmplitudeScaling,
  262.                                             float FrequencyScaling, LFOArithSelect ModulationMode,
  263.                                             float FreqForMultisampling)
  264.     {
  265.         LFOGenRec*                LFOGen;
  266.         long                            ListLimit;
  267.         long                            ListScan;
  268.         LFOOneStateRec*        ListTail;
  269.         long                            MaxPreOrigin;
  270.  
  271.         CheckPtrExistence(LFOListSpec);
  272.         if (LFOGenFreeList != NIL)
  273.             {
  274.                 LFOGen = LFOGenFreeList;
  275.                 LFOGenFreeList = LFOGenFreeList->GarbageLink;
  276.             }
  277.          else
  278.             {
  279.                 LFOGen = (LFOGenRec*)AllocPtrCanFail(sizeof(LFOGenRec),"LFOGenRec");
  280.                 if (LFOGen == NIL)
  281.                     {
  282.                         return NIL;
  283.                     }
  284.             }
  285.  
  286.         /* calculate correction factor.  when this factor is multiplied by some */
  287.         /* thing in periods/second, it converts it to periods/update */
  288.         LFOGen->CorrectionFactor = Double2FastFixed(1 / TicksPerSecond);
  289.  
  290.         /* remember the envelope rate */
  291.         LFOGen->EnvelopeTicksPerSecond = TicksPerSecond;
  292.  
  293.         /* build the list of thingers */
  294.         LFOGen->LFOList = NIL;
  295.         ListTail = NIL;
  296.         ListLimit = LFOListSpecGetNumElements(LFOListSpec);
  297.         MaxPreOrigin = 0;
  298.         for (ListScan = 0; ListScan < ListLimit; ListScan += 1)
  299.             {
  300.                 LFOSpecRec*                OneLFOSpec;
  301.                 LFOOneStateRec*        ListNode;
  302.                 long                            PreOriginTime;
  303.  
  304.                 /* allocate an entry */
  305.                 if (LFOOneStateFreeList != NIL)
  306.                     {
  307.                         ListNode = LFOOneStateFreeList;
  308.                         LFOOneStateFreeList = LFOOneStateFreeList->Next;
  309.                     }
  310.                  else
  311.                     {
  312.                         ListNode = (LFOOneStateRec*)AllocPtrCanFail(sizeof(LFOOneStateRec),
  313.                             "LFOOneStateRec");
  314.                         if (ListNode == NIL)
  315.                             {
  316.                              FailurePoint1:
  317.                                 while (LFOGen->LFOList != NIL)
  318.                                     {
  319.                                         ListNode = LFOGen->LFOList;
  320.                                         LFOGen->LFOList = LFOGen->LFOList->Next;
  321.                                         DisposeEnvelopeStateRecord(ListNode->LFOAmplitudeEnvelope);
  322.                                         DisposeEnvelopeStateRecord(ListNode->LFOFrequencyEnvelope);
  323.                                         ListNode->Next = LFOOneStateFreeList;
  324.                                         LFOOneStateFreeList = ListNode;
  325.                                     }
  326.                                 LFOGen->GarbageLink = LFOGenFreeList;
  327.                                 LFOGenFreeList = LFOGen;
  328.                                 return NIL;
  329.                             }
  330.                     }
  331.                 /* initialize phase index */
  332.                 ListNode->CurrentPhase = 0;
  333.                 /* get the data to put in it */
  334.                 OneLFOSpec = LFOListSpecGetLFOSpec(LFOListSpec,ListScan);
  335.                 /* Add frequency envelope generator */
  336.                 ListNode->LFOFrequencyEnvelope = NewEnvelopeStateRecord(
  337.                     GetLFOSpecFrequencyEnvelope(OneLFOSpec),Accent1,Accent2,Accent3,Accent4,
  338.                     FrequencyHertz,FrequencyScaling,HurryUp,TicksPerSecond,&PreOriginTime);
  339.                 if (ListNode->LFOFrequencyEnvelope == NIL)
  340.                     {
  341.                      FailurePoint2:
  342.                         ListNode->Next = LFOOneStateFreeList;
  343.                         LFOOneStateFreeList = ListNode;
  344.                         goto FailurePoint1;
  345.                     }
  346.                 if (PreOriginTime > MaxPreOrigin)
  347.                     {
  348.                         MaxPreOrigin = PreOriginTime;
  349.                     }
  350.                 /* determine what mode to use and calculate amplitude */
  351.                 switch (ModulationMode)
  352.                     {
  353.                         default:
  354.                             EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation mode"));
  355.                             break;
  356.                         case eLFOArithAdditive:
  357.                             ListNode->ModulationMode = eLFOArithAdditive;
  358.                             break;
  359.                         case eLFOArithGeometric:
  360.                             ListNode->ModulationMode = eLFOArithGeometric;
  361.                             break;
  362.                         case eLFOArithDefault:
  363.                             switch (LFOSpecGetAddingMode(OneLFOSpec))
  364.                                 {
  365.                                     default:
  366.                                         EXECUTE(PRERR(ForceAbort,
  367.                                             "NewLFOGenerator:  bad value from LFOSpecGetAddingMode"));
  368.                                         break;
  369.                                     case eLFOArithmetic:
  370.                                         ListNode->ModulationMode = eLFOArithAdditive;
  371.                                         break;
  372.                                     case eLFOGeometric:
  373.                                         ListNode->ModulationMode = eLFOArithGeometric;
  374.                                         break;
  375.                                 }
  376.                             break;
  377.                     }
  378.                 /* add the amplitude envelope generator */
  379.                 ListNode->LFOAmplitudeEnvelope = NewEnvelopeStateRecord(
  380.                     GetLFOSpecAmplitudeEnvelope(OneLFOSpec),Accent1,Accent2,Accent3,Accent4,
  381.                     FrequencyHertz,AmplitudeScaling,HurryUp,TicksPerSecond,&PreOriginTime);
  382.                 if (ListNode->LFOAmplitudeEnvelope == NIL)
  383.                     {
  384.                      FailurePoint3:
  385.                         DisposeEnvelopeStateRecord(ListNode->LFOFrequencyEnvelope);
  386.                         goto FailurePoint2;
  387.                     }
  388.                 if (PreOriginTime > MaxPreOrigin)
  389.                     {
  390.                         MaxPreOrigin = PreOriginTime;
  391.                     }
  392.                 /* determine what function to use */
  393.                 ListNode->Operator = LFOSpecGetOscillatorType(OneLFOSpec);
  394.                 ListNode->ModulationMethod = LFOSpecGetModulationMode(OneLFOSpec);
  395.                 switch (ListNode->Operator)
  396.                     {
  397.                         default:
  398.                             EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad oscillator type"));
  399.                             break;
  400.                         case eLFOConstant1:
  401.                             switch (ListNode->ModulationMethod)
  402.                                 {
  403.                                     default:
  404.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  405.                                         break;
  406.                                     case eLFOAdditive:
  407.                                         ListNode->GenFunction = &AddConst;
  408.                                         break;
  409.                                     case eLFOMultiplicative:
  410.                                         ListNode->GenFunction = &MultConst;
  411.                                         break;
  412.                                     case eLFOInverseMultiplicative:
  413.                                         ListNode->GenFunction = &InvMultConst;
  414.                                         break;
  415.                                 }
  416.                             break;
  417.                         case eLFOSignedSine:
  418.                             switch (ListNode->ModulationMethod)
  419.                                 {
  420.                                     default:
  421.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  422.                                         break;
  423.                                     case eLFOAdditive:
  424.                                         ListNode->GenFunction = &AddSignSine;
  425.                                         break;
  426.                                     case eLFOMultiplicative:
  427.                                         ListNode->GenFunction = &MultSignSine;
  428.                                         break;
  429.                                     case eLFOInverseMultiplicative:
  430.                                         ListNode->GenFunction = &InvMultSignSine;
  431.                                         break;
  432.                                 }
  433.                             break;
  434.                         case eLFOPositiveSine:
  435.                             switch (ListNode->ModulationMethod)
  436.                                 {
  437.                                     default:
  438.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  439.                                         break;
  440.                                     case eLFOAdditive:
  441.                                         ListNode->GenFunction = &AddPosSine;
  442.                                         break;
  443.                                     case eLFOMultiplicative:
  444.                                         ListNode->GenFunction = &MultPosSine;
  445.                                         break;
  446.                                     case eLFOInverseMultiplicative:
  447.                                         ListNode->GenFunction = &InvMultPosSine;
  448.                                         break;
  449.                                 }
  450.                             break;
  451.                         case eLFOSignedTriangle:
  452.                             switch (ListNode->ModulationMethod)
  453.                                 {
  454.                                     default:
  455.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  456.                                         break;
  457.                                     case eLFOAdditive:
  458.                                         ListNode->GenFunction = &AddSignTriangle;
  459.                                         break;
  460.                                     case eLFOMultiplicative:
  461.                                         ListNode->GenFunction = &MultSignTriangle;
  462.                                         break;
  463.                                     case eLFOInverseMultiplicative:
  464.                                         ListNode->GenFunction = &InvMultSignTriangle;
  465.                                         break;
  466.                                 }
  467.                             break;
  468.                         case eLFOPositiveTriangle:
  469.                             switch (ListNode->ModulationMethod)
  470.                                 {
  471.                                     default:
  472.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  473.                                         break;
  474.                                     case eLFOAdditive:
  475.                                         ListNode->GenFunction = &AddPosTriangle;
  476.                                         break;
  477.                                     case eLFOMultiplicative:
  478.                                         ListNode->GenFunction = &MultPosTriangle;
  479.                                         break;
  480.                                     case eLFOInverseMultiplicative:
  481.                                         ListNode->GenFunction = &InvMultPosTriangle;
  482.                                         break;
  483.                                 }
  484.                             break;
  485.                         case eLFOSignedSquare:
  486.                             switch (ListNode->ModulationMethod)
  487.                                 {
  488.                                     default:
  489.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  490.                                         break;
  491.                                     case eLFOAdditive:
  492.                                         ListNode->GenFunction = &AddSignSquare;
  493.                                         break;
  494.                                     case eLFOMultiplicative:
  495.                                         ListNode->GenFunction = &MultSignSquare;
  496.                                         break;
  497.                                     case eLFOInverseMultiplicative:
  498.                                         ListNode->GenFunction = &InvMultSignSquare;
  499.                                         break;
  500.                                 }
  501.                             break;
  502.                         case eLFOPositiveSquare:
  503.                             switch (ListNode->ModulationMethod)
  504.                                 {
  505.                                     default:
  506.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  507.                                         break;
  508.                                     case eLFOAdditive:
  509.                                         ListNode->GenFunction = &AddPosSquare;
  510.                                         break;
  511.                                     case eLFOMultiplicative:
  512.                                         ListNode->GenFunction = &MultPosSquare;
  513.                                         break;
  514.                                     case eLFOInverseMultiplicative:
  515.                                         ListNode->GenFunction = &InvMultPosSquare;
  516.                                         break;
  517.                                 }
  518.                             break;
  519.                         case eLFOSignedRamp:
  520.                             switch (ListNode->ModulationMethod)
  521.                                 {
  522.                                     default:
  523.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  524.                                         break;
  525.                                     case eLFOAdditive:
  526.                                         ListNode->GenFunction = &AddSignRamp;
  527.                                         break;
  528.                                     case eLFOMultiplicative:
  529.                                         ListNode->GenFunction = &MultSignRamp;
  530.                                         break;
  531.                                     case eLFOInverseMultiplicative:
  532.                                         ListNode->GenFunction = &InvMultSignRamp;
  533.                                         break;
  534.                                 }
  535.                             break;
  536.                         case eLFOPositiveRamp:
  537.                             switch (ListNode->ModulationMethod)
  538.                                 {
  539.                                     default:
  540.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  541.                                         break;
  542.                                     case eLFOAdditive:
  543.                                         ListNode->GenFunction = &AddPosRamp;
  544.                                         break;
  545.                                     case eLFOMultiplicative:
  546.                                         ListNode->GenFunction = &MultPosRamp;
  547.                                         break;
  548.                                     case eLFOInverseMultiplicative:
  549.                                         ListNode->GenFunction = &InvMultPosRamp;
  550.                                         break;
  551.                                 }
  552.                             break;
  553.                         case eLFOSignedLinearFuzz:
  554.                             switch (ListNode->ModulationMethod)
  555.                                 {
  556.                                     default:
  557.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  558.                                         break;
  559.                                     case eLFOAdditive:
  560.                                         ListNode->GenFunction = &AddSignFuzz;
  561.                                         break;
  562.                                     case eLFOMultiplicative:
  563.                                         ListNode->GenFunction = &MultSignFuzz;
  564.                                         break;
  565.                                     case eLFOInverseMultiplicative:
  566.                                         ListNode->GenFunction = &InvMultSignFuzz;
  567.                                         break;
  568.                                 }
  569.                             break;
  570.                         case eLFOPositiveLinearFuzz:
  571.                             switch (ListNode->ModulationMethod)
  572.                                 {
  573.                                     default:
  574.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  575.                                         break;
  576.                                     case eLFOAdditive:
  577.                                         ListNode->GenFunction = &AddPosFuzz;
  578.                                         break;
  579.                                     case eLFOMultiplicative:
  580.                                         ListNode->GenFunction = &MultPosFuzz;
  581.                                         break;
  582.                                     case eLFOInverseMultiplicative:
  583.                                         ListNode->GenFunction = &InvMultPosFuzz;
  584.                                         break;
  585.                                 }
  586.                             break;
  587.                         case eLFOWaveTable:
  588.                             switch (ListNode->ModulationMethod)
  589.                                 {
  590.                                     default:
  591.                                         EXECUTE(PRERR(ForceAbort,"NewLFOGenerator:  bad modulation type"));
  592.                                         break;
  593.                                     case eLFOAdditive:
  594.                                         ListNode->GenFunction = &AddWaveTable;
  595.                                         break;
  596.                                     case eLFOMultiplicative:
  597.                                         ListNode->GenFunction = &MultWaveTable;
  598.                                         break;
  599.                                     case eLFOInverseMultiplicative:
  600.                                         ListNode->GenFunction = &InvMultWaveTable;
  601.                                         break;
  602.                                 }
  603.                             ListNode->WaveTableSourceSelector = NewMultisampleWaveTable(
  604.                                 GetLFOSpecSampleSelector(OneLFOSpec));
  605.                             if (ListNode->WaveTableSourceSelector == NIL)
  606.                                 {
  607.                                  FailurePoint4:
  608.                                     if (ListNode->Operator == eLFOWaveTable)
  609.                                         {
  610.                                             DisposeEnvelopeStateRecord(ListNode->LFOAmplitudeEnvelope);
  611.                                         }
  612.                                     goto FailurePoint3;
  613.                                 }
  614.                             ListNode->WaveTableWasDefined = GetMultisampleReferenceWaveTable(
  615.                                 ListNode->WaveTableSourceSelector,FreqForMultisampling,
  616.                                 &(ListNode->WaveTableMatrix),&(ListNode->FramesPerTable),
  617.                                 &(ListNode->NumberOfTables),&(ListNode->TableNumBits));
  618.                             ListNode->WaveTableIndexEnvelope = NewEnvelopeStateRecord(
  619.                                 GetLFOSpecWaveTableIndexEnvelope(OneLFOSpec),Accent1,Accent2,Accent3,
  620.                                 Accent4,FrequencyHertz,AmplitudeScaling,HurryUp,TicksPerSecond,
  621.                                 &PreOriginTime);
  622.                             if (ListNode->WaveTableIndexEnvelope == NIL)
  623.                                 {
  624.                                  FailurePoint5:
  625.                                     if (ListNode->Operator == eLFOWaveTable)
  626.                                         {
  627.                                             DisposeMultisample(ListNode->WaveTableSourceSelector);
  628.                                         }
  629.                                     goto FailurePoint4;
  630.                                 }
  631.                             if (PreOriginTime > MaxPreOrigin)
  632.                                 {
  633.                                     MaxPreOrigin = PreOriginTime;
  634.                                 }
  635.                             break;
  636.                     }
  637.                 /* link it in */
  638.                 ListNode->Next = NIL;
  639.                 if (ListTail != NIL)
  640.                     {
  641.                         ListTail->Next = ListNode;
  642.                     }
  643.                  else
  644.                     {
  645.                         LFOGen->LFOList = ListNode;
  646.                     }
  647.                 ListTail = ListNode;
  648.             }
  649.  
  650.         *MaxPreOriginTime = MaxPreOrigin;
  651.         return LFOGen;
  652.     }
  653.  
  654.  
  655. /* fix up the origin time so that envelopes start at the proper times */
  656. void                                LFOGeneratorFixEnvelopeOrigins(LFOGenRec* LFOGen,
  657.                                             long ActualPreOriginTime)
  658.     {
  659.         LFOOneStateRec*        Scan;
  660.  
  661.         CheckPtrExistence(LFOGen);
  662.         ValidateLFOGen(LFOGen);
  663.  
  664.         Scan = LFOGen->LFOList;
  665.         while (Scan != NIL)
  666.             {
  667.                 ValidateLFOOneState(Scan);
  668.                 EnvelopeStateFixUpInitialDelay(Scan->LFOAmplitudeEnvelope,ActualPreOriginTime);
  669.                 EnvelopeStateFixUpInitialDelay(Scan->LFOFrequencyEnvelope,ActualPreOriginTime);
  670.                 if (Scan->Operator == eLFOWaveTable)
  671.                     {
  672.                         EnvelopeStateFixUpInitialDelay(Scan->WaveTableIndexEnvelope,
  673.                             ActualPreOriginTime);
  674.                     }
  675.                 Scan = Scan->Next;
  676.             }
  677.     }
  678.  
  679.  
  680. /* this function computes one LFO cycle and returns the value from the LFO generator. */
  681. /* it should be called on the envelope clock. */
  682. FastFixedType                LFOGenUpdateCycle(LFOGenRec* LFOGen, FastFixedType OriginalValue)
  683.     {
  684.         LFOOneStateRec*        Scan;
  685.  
  686.         CheckPtrExistence(LFOGen);
  687.         ValidateLFOGen(LFOGen);
  688.  
  689.         Scan = LFOGen->LFOList;
  690.         if (Scan != NIL)
  691.             {
  692.                 float                            Iterator;
  693.  
  694.                 Iterator = FastFixed2Float(OriginalValue);
  695.                 while (Scan != NIL)
  696.                     {
  697.                         /* perform the calculations */
  698.                         ERROR((Scan->ModulationMode != eLFOArithAdditive)
  699.                             && (Scan->ModulationMode != eLFOArithGeometric),PRERR(AllowResume,
  700.                             "LFOGenUpdateCycle:  bad value for ModulationMode"));
  701.                         if (Scan->ModulationMode == eLFOArithAdditive)
  702.                             {
  703.                                 Iterator = (*Scan->GenFunction)(Scan,FastFixed2Float(Scan->CurrentPhase),
  704.                                     Iterator,FastFixed2Float(EnvelopeUpdate(Scan->LFOAmplitudeEnvelope)));
  705.                             }
  706.                          else
  707.                             {
  708.                                 MyBoolean                    Sign;
  709.  
  710.                                 Sign = (Iterator < 0);
  711.                                 if (Sign)
  712.                                     {
  713.                                         Iterator = - Iterator;
  714.                                     }
  715.                                 if (Iterator != 0)
  716.                                     {
  717.                                         /* the LOG2 is to normalize the values, so that 1/12 will */
  718.                                         /* be 1 halfstep */
  719.                                         Iterator = (float)FEXP((*Scan->GenFunction)(Scan,
  720.                                             FastFixed2Float(Scan->CurrentPhase),(float)FLN(Iterator),
  721.                                             FastFixed2Float(EnvelopeUpdate(
  722.                                             Scan->LFOAmplitudeEnvelope)) * (float)LOG2));
  723.                                     }
  724.                                 if (Sign)
  725.                                     {
  726.                                         Iterator = - Iterator;
  727.                                     }
  728.                             }
  729.                         Scan->CurrentPhase = (Scan->CurrentPhase
  730.                             + FastFixedTimesFastFixedToFastFixed(LFOGen->CorrectionFactor,
  731.                             EnvelopeUpdate(Scan->LFOFrequencyEnvelope)))
  732.                             & ((1L << FASTFIXEDPRECISION) - 1);
  733.                         /* go to next one */
  734.                         Scan = Scan->Next;
  735.                     }
  736.                 return Double2FastFixed(Iterator);
  737.             }
  738.          else
  739.             {
  740.                 return OriginalValue;
  741.             }
  742.     }
  743.  
  744.  
  745. /* pass the key-up impulse on to the envelopes contained inside */
  746. void                                LFOGeneratorKeyUpSustain1(LFOGenRec* LFOGen)
  747.     {
  748.         LFOOneStateRec*        Scan;
  749.  
  750.         CheckPtrExistence(LFOGen);
  751.         ValidateLFOGen(LFOGen);
  752.  
  753.         Scan = LFOGen->LFOList;
  754.         while (Scan != NIL)
  755.             {
  756.                 EnvelopeKeyUpSustain1(Scan->LFOAmplitudeEnvelope);
  757.                 EnvelopeKeyUpSustain1(Scan->LFOFrequencyEnvelope);
  758.                 if (Scan->Operator == eLFOWaveTable)
  759.                     {
  760.                         EnvelopeKeyUpSustain1(Scan->WaveTableIndexEnvelope);
  761.                     }
  762.                 Scan = Scan->Next;
  763.             }
  764.     }
  765.  
  766.  
  767. /* pass the key-up impulse on to the envelopes contained inside */
  768. void                                LFOGeneratorKeyUpSustain2(LFOGenRec* LFOGen)
  769.     {
  770.         LFOOneStateRec*        Scan;
  771.  
  772.         CheckPtrExistence(LFOGen);
  773.         ValidateLFOGen(LFOGen);
  774.  
  775.         Scan = LFOGen->LFOList;
  776.         while (Scan != NIL)
  777.             {
  778.                 EnvelopeKeyUpSustain2(Scan->LFOAmplitudeEnvelope);
  779.                 EnvelopeKeyUpSustain2(Scan->LFOFrequencyEnvelope);
  780.                 if (Scan->Operator == eLFOWaveTable)
  781.                     {
  782.                         EnvelopeKeyUpSustain2(Scan->WaveTableIndexEnvelope);
  783.                     }
  784.                 Scan = Scan->Next;
  785.             }
  786.     }
  787.  
  788.  
  789. /* pass the key-up impulse on to the envelopes contained inside */
  790. void                                LFOGeneratorKeyUpSustain3(LFOGenRec* LFOGen)
  791.     {
  792.         LFOOneStateRec*        Scan;
  793.  
  794.         CheckPtrExistence(LFOGen);
  795.         ValidateLFOGen(LFOGen);
  796.  
  797.         Scan = LFOGen->LFOList;
  798.         while (Scan != NIL)
  799.             {
  800.                 EnvelopeKeyUpSustain3(Scan->LFOAmplitudeEnvelope);
  801.                 EnvelopeKeyUpSustain3(Scan->LFOFrequencyEnvelope);
  802.                 if (Scan->Operator == eLFOWaveTable)
  803.                     {
  804.                         EnvelopeKeyUpSustain3(Scan->WaveTableIndexEnvelope);
  805.                     }
  806.                 Scan = Scan->Next;
  807.             }
  808.     }
  809.  
  810.  
  811. /* retrigger envelopes from the origin point */
  812. void                                LFOGeneratorRetriggerFromOrigin(LFOGenRec* LFOGen, float Accent1,
  813.                                             float Accent2, float Accent3, float Accent4, float FrequencyHertz,
  814.                                             float HurryUp, float TicksPerSecond, float AmplitudeScaling,
  815.                                             float FrequencyScaling, MyBoolean ActuallyRetrigger)
  816.     {
  817.         LFOOneStateRec*        Scan;
  818.  
  819.         CheckPtrExistence(LFOGen);
  820.         ValidateLFOGen(LFOGen);
  821.  
  822.         Scan = LFOGen->LFOList;
  823.         while (Scan != NIL)
  824.             {
  825.                 EnvelopeRetriggerFromOrigin(Scan->LFOAmplitudeEnvelope,Accent1,Accent2,
  826.                     Accent3,Accent4,FrequencyHertz,AmplitudeScaling,HurryUp,
  827.                     LFOGen->EnvelopeTicksPerSecond,ActuallyRetrigger);
  828.                 EnvelopeRetriggerFromOrigin(Scan->LFOFrequencyEnvelope,Accent1,Accent2,
  829.                     Accent3,Accent4,FrequencyHertz,FrequencyScaling,HurryUp,
  830.                     LFOGen->EnvelopeTicksPerSecond,ActuallyRetrigger);
  831.                 if (Scan->Operator == eLFOWaveTable)
  832.                     {
  833.                         EnvelopeRetriggerFromOrigin(Scan->WaveTableIndexEnvelope,Accent1,Accent2,
  834.                             Accent3,Accent4,FrequencyHertz,FrequencyScaling,HurryUp,
  835.                             LFOGen->EnvelopeTicksPerSecond,ActuallyRetrigger);
  836.                     }
  837.                 Scan = Scan->Next;
  838.             }
  839.     }
  840.  
  841.  
  842. /* dispose the LFO generator */
  843. void                                DisposeLFOGenerator(LFOGenRec* LFOGen)
  844.     {
  845.         LFOOneStateRec*        StateScan;
  846.  
  847.         CheckPtrExistence(LFOGen);
  848.         ValidateLFOGen(LFOGen);
  849.  
  850.         StateScan = LFOGen->LFOList;
  851.  
  852.         /* dispose of the master record */
  853.         LFOGen->GarbageLink = LFOGenFreeList;
  854.         LFOGenFreeList = LFOGen;
  855.  
  856.         /* dispose of each element */
  857.         while (StateScan != NIL)
  858.             {
  859.                 LFOOneStateRec*        Temp;
  860.  
  861.                 ValidateLFOOneState(StateScan);
  862.                 if (StateScan->Operator == eLFOWaveTable)
  863.                     {
  864.                         DisposeMultisample(StateScan->WaveTableSourceSelector);
  865.                         DisposeEnvelopeStateRecord(StateScan->WaveTableIndexEnvelope);
  866.                     }
  867.                 DisposeEnvelopeStateRecord(StateScan->LFOAmplitudeEnvelope);
  868.                 DisposeEnvelopeStateRecord(StateScan->LFOFrequencyEnvelope);
  869.                 Temp = StateScan;
  870.                 StateScan = StateScan->Next;
  871.                 Temp->Next = LFOOneStateFreeList;
  872.                 LFOOneStateFreeList = Temp;
  873.             }
  874.     }
  875.  
  876.  
  877. static float                        AddConst(LFOOneStateRec* State, float Phase,
  878.                                                     float OriginalValue, float Amplitude)
  879.     {
  880.         return OriginalValue + Amplitude;
  881.     }
  882.  
  883.  
  884. static float                        AddSignSine(LFOOneStateRec* State, float Phase,
  885.                                                     float OriginalValue, float Amplitude)
  886.     {
  887.         return OriginalValue + Amplitude * FSIN(Phase * TWOPI);
  888.     }
  889.  
  890.  
  891. static float                        AddPosSine(LFOOneStateRec* State, float Phase,
  892.                                                     float OriginalValue, float Amplitude)
  893.     {
  894.         return OriginalValue + Amplitude * 0.5 * (1 + FSIN(Phase * TWOPI));
  895.     }
  896.  
  897.  
  898. static float                        AddSignTriangle(LFOOneStateRec* State, float Phase,
  899.                                                     float OriginalValue, float Amplitude)
  900.     {
  901.         if (Phase < 0.25)
  902.             {
  903.             }
  904.         else if (Phase < 0.75)
  905.             {
  906.                 Phase = 0.5 - Phase;
  907.             }
  908.         else
  909.             {
  910.                 Phase = Phase - 1;
  911.             }
  912.         return OriginalValue + Phase * 4 * Amplitude;
  913.     }
  914.  
  915.  
  916. static float                        AddPosTriangle(LFOOneStateRec* State, float Phase,
  917.                                                     float OriginalValue, float Amplitude)
  918.     {
  919.         if (Phase < 0.25)
  920.             {
  921.             }
  922.         else if (Phase < 0.75)
  923.             {
  924.                 Phase = 0.5 - Phase;
  925.             }
  926.         else
  927.             {
  928.                 Phase = Phase - 1;
  929.             }
  930.         return OriginalValue + (Phase + 1) * 2 * Amplitude;
  931.     }
  932.  
  933.  
  934. static float                        AddSignSquare(LFOOneStateRec* State, float Phase,
  935.                                                     float OriginalValue, float Amplitude)
  936.     {
  937.         if (Phase < 0.5)
  938.             {
  939.                 return OriginalValue + Amplitude;
  940.             }
  941.          else
  942.             {
  943.                 return OriginalValue - Amplitude;
  944.             }
  945.     }
  946.  
  947.  
  948. static float                        AddPosSquare(LFOOneStateRec* State, float Phase,
  949.                                                     float OriginalValue, float Amplitude)
  950.     {
  951.         if (Phase < 0.5)
  952.             {
  953.                 return OriginalValue + Amplitude;
  954.             }
  955.          else
  956.             {
  957.                 return OriginalValue;
  958.             }
  959.     }
  960.  
  961.  
  962. static float                        AddSignRamp(LFOOneStateRec* State, float Phase,
  963.                                                     float OriginalValue, float Amplitude)
  964.     {
  965.         return OriginalValue + Amplitude * (2 * Phase - 1);
  966.     }
  967.  
  968.  
  969. static float                        AddPosRamp(LFOOneStateRec* State, float Phase,
  970.                                                     float OriginalValue, float Amplitude)
  971.     {
  972.         return OriginalValue + Amplitude * Phase;
  973.     }
  974.  
  975.  
  976. static float                        AddSignFuzz(LFOOneStateRec* State, float Phase,
  977.                                                     float OriginalValue, float Amplitude)
  978.     {
  979.         long                                    OldSeed;
  980.         float                                    ReturnValue;
  981.  
  982.         OldSeed = SetParkAndMillerRandomSeed(RandomSeed);
  983.         ReturnValue = ((((float)ParkAndMillerRandom() - PARKANDMILLERMINIMUM)
  984.             / (PARKANDMILLERMAXIMUM - PARKANDMILLERMINIMUM - 1) * 2) - 1) * Amplitude
  985.             + OriginalValue;
  986.         RandomSeed = SetParkAndMillerRandomSeed(OldSeed);
  987.         return ReturnValue;
  988.     }
  989.  
  990.  
  991. static float                        AddPosFuzz(LFOOneStateRec* State, float Phase,
  992.                                                     float OriginalValue, float Amplitude)
  993.     {
  994.         long                                    OldSeed;
  995.         float                                    ReturnValue;
  996.  
  997.         OldSeed = SetParkAndMillerRandomSeed(RandomSeed);
  998.         ReturnValue = (((float)ParkAndMillerRandom() - PARKANDMILLERMINIMUM)
  999.             / (PARKANDMILLERMAXIMUM - PARKANDMILLERMINIMUM - 1) * Amplitude)
  1000.             + OriginalValue;
  1001.         RandomSeed = SetParkAndMillerRandomSeed(OldSeed);
  1002.         return ReturnValue;
  1003.     }
  1004.  
  1005.  
  1006. static float                        MultConst(LFOOneStateRec* State, float Phase,
  1007.                                                     float OriginalValue, float Amplitude)
  1008.     {
  1009.         return OriginalValue * Amplitude;
  1010.     }
  1011.  
  1012.  
  1013. static float                        MultSignSine(LFOOneStateRec* State, float Phase,
  1014.                                                     float OriginalValue, float Amplitude)
  1015.     {
  1016.         return OriginalValue * Amplitude * FSIN(Phase * TWOPI);
  1017.     }
  1018.  
  1019.  
  1020. static float                        MultPosSine(LFOOneStateRec* State, float Phase,
  1021.                                                     float OriginalValue, float Amplitude)
  1022.     {
  1023.         return OriginalValue * Amplitude * 0.5 * (1 + FSIN(Phase * TWOPI));
  1024.     }
  1025.  
  1026.  
  1027. static float                        MultSignTriangle(LFOOneStateRec* State, float Phase,
  1028.                                                     float OriginalValue, float Amplitude)
  1029.     {
  1030.         if (Phase < 0.25)
  1031.             {
  1032.             }
  1033.         else if (Phase < 0.75)
  1034.             {
  1035.                 Phase = 0.5 - Phase;
  1036.             }
  1037.         else
  1038.             {
  1039.                 Phase = Phase - 1;
  1040.             }
  1041.         return OriginalValue * Phase * 4 * Amplitude;
  1042.     }
  1043.  
  1044.  
  1045. static float                        MultPosTriangle(LFOOneStateRec* State, float Phase,
  1046.                                                     float OriginalValue, float Amplitude)
  1047.     {
  1048.         if (Phase < 0.25)
  1049.             {
  1050.             }
  1051.         else if (Phase < 0.75)
  1052.             {
  1053.                 Phase = 0.5 - Phase;
  1054.             }
  1055.         else
  1056.             {
  1057.                 Phase = Phase - 1;
  1058.             }
  1059.         return OriginalValue * (Phase + 1) * 2 * Amplitude;
  1060.     }
  1061.  
  1062.  
  1063. static float                        MultSignSquare(LFOOneStateRec* State, float Phase,
  1064.                                                     float OriginalValue, float Amplitude)
  1065.     {
  1066.         if (Phase < 0.5)
  1067.             {
  1068.                 return OriginalValue * Amplitude;
  1069.             }
  1070.          else
  1071.             {
  1072.                 return OriginalValue * - Amplitude;
  1073.             }
  1074.     }
  1075.  
  1076.  
  1077. static float                        MultPosSquare(LFOOneStateRec* State, float Phase,
  1078.                                                     float OriginalValue, float Amplitude)
  1079.     {
  1080.         if (Phase < 0.5)
  1081.             {
  1082.                 return OriginalValue * Amplitude;
  1083.             }
  1084.          else
  1085.             {
  1086.                 return 0;
  1087.             }
  1088.     }
  1089.  
  1090.  
  1091. static float                        MultSignRamp(LFOOneStateRec* State, float Phase,
  1092.                                                     float OriginalValue, float Amplitude)
  1093.     {
  1094.         return OriginalValue * Amplitude * (2 * Phase - 1);
  1095.     }
  1096.  
  1097.  
  1098. static float                        MultPosRamp(LFOOneStateRec* State, float Phase,
  1099.                                                     float OriginalValue, float Amplitude)
  1100.     {
  1101.         return OriginalValue * Amplitude * Phase;
  1102.     }
  1103.  
  1104.  
  1105. static float                        MultSignFuzz(LFOOneStateRec* State, float Phase,
  1106.                                                     float OriginalValue, float Amplitude)
  1107.     {
  1108.         long                                    OldSeed;
  1109.         float                                    ReturnValue;
  1110.  
  1111.         OldSeed = SetParkAndMillerRandomSeed(RandomSeed);
  1112.         ReturnValue = ((((float)ParkAndMillerRandom() - PARKANDMILLERMINIMUM)
  1113.             / (PARKANDMILLERMAXIMUM - PARKANDMILLERMINIMUM - 1) * 2) - 1) * Amplitude
  1114.             * OriginalValue;
  1115.         RandomSeed = SetParkAndMillerRandomSeed(OldSeed);
  1116.         return ReturnValue;
  1117.     }
  1118.  
  1119.  
  1120. static float                        MultPosFuzz(LFOOneStateRec* State, float Phase,
  1121.                                                     float OriginalValue, float Amplitude)
  1122.     {
  1123.         long                                    OldSeed;
  1124.         float                                    ReturnValue;
  1125.  
  1126.         OldSeed = SetParkAndMillerRandomSeed(RandomSeed);
  1127.         ReturnValue = (((float)ParkAndMillerRandom() - PARKANDMILLERMINIMUM)
  1128.             / (PARKANDMILLERMAXIMUM - PARKANDMILLERMINIMUM - 1) * Amplitude)
  1129.             * OriginalValue;
  1130.         RandomSeed = SetParkAndMillerRandomSeed(OldSeed);
  1131.         return ReturnValue;
  1132.     }
  1133.  
  1134.  
  1135. static float                        InvMultConst(LFOOneStateRec* State, float Phase,
  1136.                                                     float OriginalValue, float Amplitude)
  1137.     {
  1138.         return OriginalValue * (1 - Amplitude);
  1139.     }
  1140.  
  1141.  
  1142. static float                        InvMultSignSine(LFOOneStateRec* State, float Phase,
  1143.                                                     float OriginalValue, float Amplitude)
  1144.     {
  1145.         return OriginalValue * (1 - Amplitude * FSIN(Phase * TWOPI));
  1146.     }
  1147.  
  1148.  
  1149. static float                        InvMultPosSine(LFOOneStateRec* State, float Phase,
  1150.                                                     float OriginalValue, float Amplitude)
  1151.     {
  1152.         return OriginalValue * (1 - Amplitude * 0.5 * (1 + FSIN(Phase * TWOPI)));
  1153.     }
  1154.  
  1155.  
  1156. static float                        InvMultSignTriangle(LFOOneStateRec* State, float Phase,
  1157.                                                     float OriginalValue, float Amplitude)
  1158.     {
  1159.         if (Phase < 0.25)
  1160.             {
  1161.             }
  1162.         else if (Phase < 0.75)
  1163.             {
  1164.                 Phase = 0.5 - Phase;
  1165.             }
  1166.         else
  1167.             {
  1168.                 Phase = Phase - 1;
  1169.             }
  1170.         return OriginalValue * (1 - Phase * 4 * Amplitude);
  1171.     }
  1172.  
  1173.  
  1174. static float                        InvMultPosTriangle(LFOOneStateRec* State, float Phase,
  1175.                                                     float OriginalValue, float Amplitude)
  1176.     {
  1177.         if (Phase < 0.25)
  1178.             {
  1179.             }
  1180.         else if (Phase < 0.75)
  1181.             {
  1182.                 Phase = 0.5 - Phase;
  1183.             }
  1184.         else
  1185.             {
  1186.                 Phase = Phase - 1;
  1187.             }
  1188.         return OriginalValue * (1 - ((Phase + 1) * 2 * Amplitude));
  1189.     }
  1190.  
  1191.  
  1192. static float                        InvMultSignSquare(LFOOneStateRec* State, float Phase,
  1193.                                                     float OriginalValue, float Amplitude)
  1194.     {
  1195.         if (Phase < 0.5)
  1196.             {
  1197.                 return OriginalValue * (1 - Amplitude);
  1198.             }
  1199.          else
  1200.             {
  1201.                 return OriginalValue * (1 + Amplitude);
  1202.             }
  1203.     }
  1204.  
  1205.  
  1206. static float                        InvMultPosSquare(LFOOneStateRec* State, float Phase,
  1207.                                                     float OriginalValue, float Amplitude)
  1208.     {
  1209.         if (Phase < 0.5)
  1210.             {
  1211.                 return OriginalValue * (1 - Amplitude);
  1212.             }
  1213.          else
  1214.             {
  1215.                 return OriginalValue;
  1216.             }
  1217.     }
  1218.  
  1219.  
  1220. static float                        InvMultSignRamp(LFOOneStateRec* State, float Phase,
  1221.                                                     float OriginalValue, float Amplitude)
  1222.     {
  1223.         return OriginalValue * (1 - Amplitude * (2 * Phase - 1));
  1224.     }
  1225.  
  1226.  
  1227. static float                        InvMultPosRamp(LFOOneStateRec* State, float Phase,
  1228.                                                     float OriginalValue, float Amplitude)
  1229.     {
  1230.         return OriginalValue * (1 - Amplitude * Phase);
  1231.     }
  1232.  
  1233.  
  1234. static float                        InvMultSignFuzz(LFOOneStateRec* State, float Phase,
  1235.                                                     float OriginalValue, float Amplitude)
  1236.     {
  1237.         long                                    OldSeed;
  1238.         float                                    ReturnValue;
  1239.  
  1240.         OldSeed = SetParkAndMillerRandomSeed(RandomSeed);
  1241.         ReturnValue = (1 - ((((float)ParkAndMillerRandom() - PARKANDMILLERMINIMUM)
  1242.             / (PARKANDMILLERMAXIMUM - PARKANDMILLERMINIMUM - 1) * 2) - 1) * Amplitude)
  1243.             * OriginalValue;
  1244.         RandomSeed = SetParkAndMillerRandomSeed(OldSeed);
  1245.         return ReturnValue;
  1246.     }
  1247.  
  1248.  
  1249. static float                        InvMultPosFuzz(LFOOneStateRec* State, float Phase,
  1250.                                                     float OriginalValue, float Amplitude)
  1251.     {
  1252.         long                                    OldSeed;
  1253.         float                                    ReturnValue;
  1254.  
  1255.         OldSeed = SetParkAndMillerRandomSeed(RandomSeed);
  1256.         ReturnValue = (1 - (((float)ParkAndMillerRandom() - PARKANDMILLERMINIMUM)
  1257.             / (PARKANDMILLERMAXIMUM - PARKANDMILLERMINIMUM - 1) * Amplitude))
  1258.             * OriginalValue;
  1259.         RandomSeed = SetParkAndMillerRandomSeed(OldSeed);
  1260.         return ReturnValue;
  1261.     }
  1262.  
  1263.  
  1264. static FastFixedType        CalcWaveTableValue(LFOOneStateRec* State, float Phase)
  1265.     {
  1266.         FastFixedType                    Index;
  1267.         LongLongRec                        FrameIndex;
  1268.         signed long                        Final; /* both 16-bit int & largefixedsigned */
  1269.  
  1270.         ERROR(!State->WaveTableWasDefined,PRERR(ForceAbort,
  1271.             "CalcWaveTableValue:  no wave table"));
  1272.  
  1273.         Index = EnvelopeUpdate(State->WaveTableIndexEnvelope);
  1274.         if (Index < 0)
  1275.             {
  1276.                 Index = 0;
  1277.             }
  1278.         else if (Index > Int2FastFixed(State->NumberOfTables - 1))
  1279.             {
  1280.                 Index = Int2FastFixed(State->NumberOfTables - 1);
  1281.             }
  1282.         Double2LongLong(Phase,FrameIndex);
  1283.         if (State->TableNumBits == eSample8bit)
  1284.             {
  1285.                 /* 8-bit */
  1286.                 if (FastFixed2Int(Index) == State->NumberOfTables - 1)
  1287.                     {
  1288.                         /* this is done in case the wave table index is at the maximum, */
  1289.                         /* in which case there is no table+1 to interpolate with. */
  1290.                         signed char*                WaveData;
  1291.  
  1292.                         FastFixedType                LeftWeight;
  1293.                         long                                ArraySubscript;
  1294.                         signed long                    LeftValue;
  1295.                         signed long                    RightValue;
  1296.  
  1297.                         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1298.                             Index)]),sizeof(State->WaveTableMatrix[FastFixed2Int(Index)]));
  1299.                         WaveData = (signed char*)(State->WaveTableMatrix[FastFixed2Int(Index)]);
  1300.  
  1301.                         LeftWeight = LongLongLowHalf(FrameIndex) >> (32 - FASTFIXEDPRECISION);
  1302.                         ArraySubscript = LongLongHighHalf(FrameIndex) & (State->FramesPerTable - 1);
  1303.                         /* L+F(R-L) */
  1304.                         LeftValue = ((signed long)WaveData[ArraySubscript]) << 8; /* convert to 16-bit */
  1305.                         RightValue = ((signed long)WaveData[ArraySubscript + 1]) << 8; /* to 16-bit */
  1306.                         Final = LeftValue + ((LeftWeight * (RightValue - LeftValue)) >> 15);
  1307.                     }
  1308.                  else
  1309.                     {
  1310.                         signed char*                WaveData0;
  1311.                         signed char*                WaveData1;
  1312.                         FastFixedType                Wave0Weight;
  1313.  
  1314.                         FastFixedType                LeftWeight;
  1315.                         long                                ArraySubscript;
  1316.                         signed long                    Left0Value;
  1317.                         signed long                    Right0Value;
  1318.                         signed long                    Left1Value;
  1319.                         signed long                    Right1Value;
  1320.                         FastFixedType                Wave0Temp;
  1321.  
  1322.                         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1323.                             Index)]),sizeof(State->WaveTableMatrix[FastFixed2Int(Index)]));
  1324.                         WaveData0 = (signed char*)(State->WaveTableMatrix[
  1325.                             FastFixed2Int(Index)]);
  1326.                         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1327.                             Index) + 1]),sizeof(State->WaveTableMatrix[FastFixed2Int(Index) + 1]));
  1328.                         WaveData1 = (signed char*)(State->WaveTableMatrix[
  1329.                             FastFixed2Int(Index) + 1]);
  1330.                         Wave0Weight = Index & FASTFIXEDFRACTMASK;
  1331.  
  1332.                         LeftWeight = LongLongLowHalf(FrameIndex) >> (32 - FASTFIXEDPRECISION);
  1333.                         ArraySubscript = LongLongHighHalf(FrameIndex) & (State->FramesPerTable - 1);
  1334.                         /* L+F(R-L) -- applied twice */
  1335.                         Left0Value = ((signed long)WaveData0[ArraySubscript]) << 8; /* convert to 16-bit */
  1336.                         Right0Value = ((signed long)WaveData0[ArraySubscript + 1]) << 8; /* to 16-bit */
  1337.                         Left1Value = ((signed long)WaveData1[ArraySubscript]) << 8; /* convert to 16-bit */
  1338.                         Right1Value = ((signed long)WaveData1[ArraySubscript + 1]) << 8; /* to 16-bit */
  1339.                         Wave0Temp = Left0Value + ((LeftWeight * (Right0Value - Left0Value)) >> 15);
  1340.                         Final = Wave0Temp + ((Wave0Weight * (Left1Value + ((LeftWeight
  1341.                             * (Right1Value - Left1Value)) >> 15) - Wave0Temp)) >> 15);
  1342.                     }
  1343.             }
  1344.          else
  1345.             {
  1346.                 /* 16-bit */
  1347.                 if (FastFixed2Int(Index) == State->NumberOfTables - 1)
  1348.                     {
  1349.                         /* this is done in case the wave table index is at the maximum, */
  1350.                         /* in which case there is no table+1 to interpolate with. */
  1351.                         signed short*                WaveData;
  1352.  
  1353.                         FastFixedType                LeftWeight;
  1354.                         long                                ArraySubscript;
  1355.                         signed long                    LeftValue;
  1356.                         signed long                    RightValue;
  1357.  
  1358.                         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1359.                             Index)]),sizeof(State->WaveTableMatrix[FastFixed2Int(Index)]));
  1360.                         WaveData = (signed short*)(State->WaveTableMatrix[FastFixed2Int(Index)]);
  1361.  
  1362.                         LeftWeight = LongLongLowHalf(FrameIndex) >> (32 - FASTFIXEDPRECISION);
  1363.                         ArraySubscript = LongLongHighHalf(FrameIndex) & (State->FramesPerTable - 1);
  1364.                         /* L+F(R-L) */
  1365.                         LeftValue = WaveData[ArraySubscript];
  1366.                         RightValue = WaveData[ArraySubscript + 1];
  1367.                         Final = LeftValue + ((LeftWeight * (RightValue - LeftValue)) >> 15);
  1368.                     }
  1369.                  else
  1370.                     {
  1371.                         signed short*                WaveData0;
  1372.                         signed short*                WaveData1;
  1373.                         FastFixedType                Wave0Weight;
  1374.  
  1375.                         FastFixedType                LeftWeight;
  1376.                         long                                ArraySubscript;
  1377.                         signed long                    Left0Value;
  1378.                         signed long                    Right0Value;
  1379.                         signed long                    Left1Value;
  1380.                         signed long                    Right1Value;
  1381.                         FastFixedType                Wave0Temp;
  1382.  
  1383.                         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1384.                             Index)]),sizeof(State->WaveTableMatrix[FastFixed2Int(Index)]));
  1385.                         WaveData0 = (signed short*)(State->WaveTableMatrix[
  1386.                             FastFixed2Int(Index)]);
  1387.                         PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
  1388.                             Index) + 1]),sizeof(State->WaveTableMatrix[FastFixed2Int(Index) + 1]));
  1389.                         WaveData1 = (signed short*)(State->WaveTableMatrix[
  1390.                             FastFixed2Int(Index) + 1]);
  1391.                         Wave0Weight = Index & FASTFIXEDFRACTMASK;
  1392.  
  1393.                         LeftWeight = LongLongLowHalf(FrameIndex) >> (32 - FASTFIXEDPRECISION);
  1394.                         ArraySubscript = LongLongHighHalf(FrameIndex) & (State->FramesPerTable - 1);
  1395.                         /* L+F(R-L) -- applied twice */
  1396.                         Left0Value = WaveData0[ArraySubscript];
  1397.                         Right0Value = WaveData0[ArraySubscript + 1];
  1398.                         Left1Value = WaveData1[ArraySubscript];
  1399.                         Right1Value = WaveData1[ArraySubscript + 1];
  1400.                         Wave0Temp = Left0Value + ((LeftWeight * (Right0Value - Left0Value)) >> 15);
  1401.                         Final = Wave0Temp + ((Wave0Weight * (Left1Value + ((LeftWeight
  1402.                             * (Right1Value - Left1Value)) >> 15)) - Wave0Temp) >> 15);
  1403.                     }
  1404.             }
  1405.         return Final;
  1406.     }
  1407.  
  1408.  
  1409. static float                        AddWaveTable(LFOOneStateRec* State, float Phase,
  1410.                                                     float OriginalValue, float Amplitude)
  1411.     {
  1412.         if (State->WaveTableWasDefined)
  1413.             {
  1414.                 return OriginalValue + Amplitude
  1415.                     * ((float)CalcWaveTableValue(State,Phase) / MAX16BIT);
  1416.             }
  1417.          else
  1418.             {
  1419.                 return OriginalValue;
  1420.             }
  1421.     }
  1422.  
  1423.  
  1424. static float                        MultWaveTable(LFOOneStateRec* State, float Phase,
  1425.                                                     float OriginalValue, float Amplitude)
  1426.     {
  1427.         if (State->WaveTableWasDefined)
  1428.             {
  1429.                 return OriginalValue * Amplitude
  1430.                     * ((float)CalcWaveTableValue(State,Phase) / MAX16BIT);
  1431.             }
  1432.          else
  1433.             {
  1434.                 return 0;
  1435.             }
  1436.     }
  1437.  
  1438.  
  1439. static float                        InvMultWaveTable(LFOOneStateRec* State, float Phase,
  1440.                                                     float OriginalValue, float Amplitude)
  1441.     {
  1442.         if (State->WaveTableWasDefined)
  1443.             {
  1444.                 return OriginalValue * (1 - Amplitude
  1445.                     * ((float)CalcWaveTableValue(State,Phase) / MAX16BIT));
  1446.             }
  1447.          else
  1448.             {
  1449.                 return OriginalValue;
  1450.             }
  1451.     }
  1452.